package component.button;

import component.theme.ThisFont;
import component.util.MaterialColors;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;

public class MaterialButton extends JButton {
    public static MaterialButton BlueButton(String text, Icon icon){
        MaterialButton button = new MaterialButton(text,icon);
        button.setColor(MaterialColors.BLUE_600);
        button.setOnPressedColor(MaterialColors.BLUE_700);
        button.setFocusedColor(MaterialColors.BLUE_500);
        button.setTextColor(MaterialColors.WHITE);
        button.setFocusedTextColor(MaterialColors.WHITE);
        button.setOnPressedTextColor(MaterialColors.WHITE);
        return button;
    }
    public static MaterialButton ShadowButton(String text, Icon icon){
        MaterialButton button = new MaterialButton(text,icon);
        button.setColor(MaterialColors.TRANSPARENT);
        button.setOnPressedColor(MaterialColors.TRANSPARENT);
        button.setFocusedColor(MaterialColors.TRANSPARENT);
        button.setTextColor(MaterialColors.BLUE_600);
        button.setFocusedTextColor(MaterialColors.BLUE_600);
        button.setOnPressedTextColor(MaterialColors.BLUE_800);
        return button;
    }
    protected Color color;
    protected Color textColor;
    protected Color hoverColor;
    protected Color hoverTextColor;
    protected Color onPressedColor;
    protected Color onPressedTextColor;
    protected Color hintColor = MaterialColors.YELLOW_400;
    protected Icon icon;
    protected String text;
    protected int arch = 10;
    private Integer clickX = null;
    private Integer clickY = null;
    final private int PADDING_SHADOW_RIGHT = 3;
    final private int PADDING_SHADOW_BOTTOM = 3;
    private Color backColor;
    private boolean hover;
    public MaterialButton(){
        this(null,null,null);
    }

    public MaterialButton(Icon icon){
        this(null,icon,null);
    }

    public MaterialButton(String text){
        this(text,null,null);
    }

    public MaterialButton(String text, Icon icon){
        this(text, icon, null);
    }

    public MaterialButton(String text, Icon icon, Color color){
        this(text, icon, color, null);

    }

    public MaterialButton(String text, Icon icon, Color color, Color textColor){
        super(text, icon);
        this.color = color;
        this.icon = icon;
        this.text = text;
        this.textColor = textColor;
        this.hoverTextColor = textColor;
        this.hoverColor = color;
        this.onPressedColor = color;
        this.onPressedTextColor = textColor;
        initial();
    }

    private void initial(){
        if (this.color == null){
            this.color = MaterialColors.BLUE_600;
        } else if (this.textColor == null){
            this.textColor = MaterialColors.WHITE;
        }
        setFont(ThisFont.SMALL_BOLD_FONT);
        setOpaque(false);
        setBackground(color);
        setForeground(textColor);
        setFocusPainted(false);
        setBorderPainted(false);
        setContentAreaFilled(false);
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                setForeground(hoverTextColor);
                setBackground(hoverColor);
                hover = true;
                repaint();
            }

            @Override
            public void mouseExited(MouseEvent e) {
                setForeground(textColor);
                setBackground(color);
                hover = false;
                repaint();
            }

            @Override
            public void mousePressed(MouseEvent e) {
                setForeground(onPressedTextColor);
                setBackground(onPressedColor);
                MaterialButton.this.clickX = e.getX();
                MaterialButton.this.clickY = e.getY();
                repaint();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                setForeground(textColor);
                MaterialButton.this.clickX = null;
                MaterialButton.this.clickY = null;
                repaint();
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        int h = getHeight();
        int w = getWidth();
        int r = arch;
        Color toPaintColor = color;
        float tran = 0.9f;
        Graphics2D g2d = (Graphics2D) g.create();
        //绘制阴影渐变
        GradientPaint p1;
        GradientPaint p2;
        p1 = new GradientPaint(0, 0, new Color(100, 100, 100), 0, h, new Color(128, 128,128), true);
        p2 = new GradientPaint(0, 1, new Color(255, 255, 255, 100), 0, h, new Color(0, 0, 0, 50), true);
        //设置抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Area round = new Area(new RoundRectangle2D.Double(1, 1, w - 3,h - 3, r, r));
        Area shadow = new Area(new RoundRectangle2D.Double(1,1, w - 2,h - 2, r, r));
        Area shadow2 = new Area(new RoundRectangle2D.Double(2,2,w - 2 ,h - 2,r,r));
        //判断鼠标事件选定背景颜色
        if (getModel().isPressed()){
            p1 = new GradientPaint(0, 0, new Color(100, 100, 100), 0, h, new Color(168, 168,168), true);
            p2 = new GradientPaint(0, 1, new Color(255, 255, 255, 100), 0, h, new Color(0, 0, 0, 50), true);
            if (onPressedColor == color){
                tran = 1f;
            } else {
                toPaintColor = onPressedColor;
            }
        } else if (hover) {
            p1 = new GradientPaint(0, 0, new Color(100, 100, 100), 0, h, new Color(0, 0, 0), true);
            p2 = new GradientPaint(0, 1, new Color(255, 255, 255, 100), 0, h, new Color(0, 0, 0, 50), true);
            if (hoverColor == color){
                tran = 1f;
            } else {
                toPaintColor = hoverColor;
            }
        } else{
            if (hoverColor != color || onPressedColor != color){
                tran = 1f;
            }
            toPaintColor = color;
        }
        //绘制阴影以及圆角矩形
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));
        g2d.setPaint(p1);
        g2d.fill(shadow);
        g2d.setPaint(p2);
        g2d.fill(shadow2);
        GradientPaint paint1 = new GradientPaint(0,0,toPaintColor,0,0,toPaintColor);
        g2d.setPaint(paint1);
        g2d.fill(round);
        //绘制点击效果
        super.paintComponent(g);
        if (clickX != null && clickY != null){
            GradientPaint paint2 = new GradientPaint(0,0,hintColor,0,0,hintColor);
            g2d.setPaint(paint2);
            int deltaX = h / 6;
            int deltaY = h / 6;
            g2d.fillOval(clickX - deltaX,clickY - deltaY,deltaX * 2,deltaY * 2);
        }
        g2d.dispose();
    }

    @Override
    public void setMargin(Insets m) {
        super.setMargin(new Insets(m.top + 3,m.left + 3, m.bottom + 3, m.right + 3));
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
        this.setBackground(color);
    }

    public Color getTextColor() {
        return textColor;
    }

    public void setTextColor(Color textColor) {
        this.textColor = textColor;
        this.setForeground(textColor);
    }

    public Color getFocusedColor() {
        return hoverColor;
    }

    public void setFocusedColor(Color hoverColor) {
        this.hoverColor = hoverColor;
        repaint();
    }

    public Color getFocusedTextColor() {
        return hoverTextColor;
    }

    public void setFocusedTextColor(Color hoverTextColor) {
        this.hoverTextColor = hoverTextColor;
        repaint();
    }

    public Color getOnPressedColor() {
        return onPressedColor;
    }

    public void setOnPressedColor(Color onPressedColor) {
        this.onPressedColor = onPressedColor;
        repaint();
    }


    public int getArch() {
        return arch;
    }

    public void setArch(int arch) {
        this.arch = arch;
        repaint();
    }

    public Color getOnPressedTextColor() {
        return onPressedTextColor;
    }

    public void setOnPressedTextColor(Color onPressedTextColor) {
        this.onPressedTextColor = onPressedTextColor;
    }

    public Color getHintColor() {
        return hintColor;
    }

    public void setHintColor(Color hintColor) {
        this.hintColor = hintColor;
    }

    @Override
    public void setBackground(Color bg) {
        super.setBackground(bg);
    }

    @Override
    public void setForeground(Color fg) {
        super.setForeground(fg);
    }
}

